#ifndef __M_LOOP_H__
#define __M_LOOP_H__

#include "util.hpp"
#include <vector>
#include <thread>
#include <mutex>
#include <atomic>
#include <condition_variable>
#include <functional>
#include "buffer.hpp"

namespace maglog {

// 异步循环器类，用于异步处理日志任务
class AsyncLooper {
    public:
        using Functor = std::function<void(Buffer &buffer)>; // 定义回调函数类型
        using ptr = std::shared_ptr<AsyncLooper>;

        // 构造函数，接受一个回调函数作为参数
        AsyncLooper(const Functor &cb)
            : _running(true), _looper_callback(cb),
              _thread(std::thread(&AsyncLooper::worker_loop, this)) {
        }

        // 析构函数，确保在销毁时停止工作线程
        ~AsyncLooper() { stop(); }

        // 停止工作线程
        void stop() { 
            _running = false; 
            _pop_cond.notify_all();
            _thread.join();
        }

        // 推送日志消息到任务队列中
        void push(const std::string &msg) {
            if (!_running) return;
            {
                std::unique_lock<std::mutex> lock(_mutex);
                _push_cond.wait(lock, [&] { return _tasks_push.writeAbleSize() >= msg.size(); });
                _tasks_push.push(msg.c_str(), msg.size());
            }
            _pop_cond.notify_all();
        }

    private:
        // 工作线程的主循环，处理任务队列中的日志消息
        void worker_loop() {
            while (true) {
                {
                    std::unique_lock<std::mutex> lock(_mutex);
                    if (!_running && _tasks_push.empty()) { return; }
                    _pop_cond.wait(lock, [&] { return !_tasks_push.empty() || !_running; });
                    _tasks_push.swap(_tasks_pop);
                }
                _push_cond.notify_all();
                _looper_callback(_tasks_pop); // 执行回调函数处理日志消息
                _tasks_pop.reset(); // 重置缓冲区
            }
        }

    private:
        Functor _looper_callback;                // 回调函数，用于处理日志消息
        std::mutex _mutex;                       // 互斥锁，用于保护任务队列
        std::atomic<bool> _running;              // 控制工作线程的运行状态
        std::condition_variable _push_cond;      // 条件变量，用于通知任务推送
        std::condition_variable _pop_cond;       // 条件变量，用于通知任务处理
        Buffer _tasks_push;                      // 用于存储待处理的日志消息
        Buffer _tasks_pop;                       // 用于处理当前批次的日志消息
        std::thread _thread;                     // 工作线程
};

} // namespace maglog

#endif // __M_LOOP_H__
